/**
 * Supabase Management API 请求封装
 */

/**
 * API 错误响应
 */
export interface ApiError {
	message: string;
	error?: string;
	statusCode?: number;
}

/**
 * API响应接口 - 适配 Supabase API 响应
 */
export interface ApiResponse<T = unknown> {
	success: boolean;
	data?: T;
	error?: ApiError;
	statusCode: number;
}

/**
 * 请求参数值类型
 */
export type RequestParamValue = string | number | boolean | null | undefined;

/**
 * 请求数据类型
 */
export type RequestData = Record<string, unknown> | unknown[] | object;

/**
 * 请求配置
 */
export interface RequestConfig {
	url: string;
	method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
	data?: RequestData;
	params?: Record<string, RequestParamValue>;
	header?: Record<string, string>;
	timeout?: number;
}

/**
 * uni.request 成功响应类型
 */
interface UniRequestSuccessResult {
	data: unknown;
	statusCode: number;
	header: Record<string, string>;
	cookies: string[];
}

/**
 * uni.request 失败响应类型
 */
interface UniRequestFailResult {
	errMsg: string;
	errno?: number;
}

/**
 * API 配置
 */
interface ApiConfig {
	baseUrl: string;
	accessToken: string;
	proxyUrl: string;
}

/**
 * 获取 API 基础 URL
 * H5 开发模式使用代理路径，其他环境直接请求
 */
function getBaseUrl(): string {
	// #ifdef H5
	// H5 开发模式使用代理
	if (process.env.NODE_ENV === "development") {
		return "/supabase-api";
	}
	// #endif
	return "https://api.supabase.com";
}

/**
 * HTTP请求类
 */
class Request {
	private config: ApiConfig = {
		baseUrl: getBaseUrl(),
		accessToken: "",
		proxyUrl: "http://192.168.31.199:3456"
	};

	/**
	 * 设置 API 配置
	 */
	setConfig(config: Partial<ApiConfig>): void {
		this.config = { ...this.config, ...config };
	}

	/**
	 * 获取当前配置
	 */
	getConfig(): ApiConfig {
		return { ...this.config };
	}

	/**
	 * 设置 Access Token
	 */
	setAccessToken(token: string): void {
		this.config.accessToken = token;
	}

	/**
	 * 设置代理服务器地址
	 */
	setProxyUrl(url: string): void {
		this.config.proxyUrl = url;
	}

	/**
	 * 通过代理服务器发送请求 (用于 PATCH 等 UniAppX 不支持的方法)
	 */
	private requestViaProxy<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>> {
		return new Promise((resolve) => {
			const fullUrl = this.buildUrl(config.url, config.params);

			const proxyData = {
				url: fullUrl,
				method: config.method || "GET",
				data: config.data,
				token: this.config.accessToken
			};

			console.log("[API Proxy Request]", proxyData);

			uni.request({
				url: `${this.config.proxyUrl}/proxy`,
				method: "POST",
				data: proxyData,
				header: {
					"Content-Type": "application/json"
				},
				timeout: config.timeout || 30000,
				success: (res: UniRequestSuccessResult) => {
					console.log("[API Proxy Response]", {
						statusCode: res.statusCode,
						data: res.data
					});

					if (res.statusCode >= 200 && res.statusCode < 300) {
						resolve({
							success: true,
							data: res.data as T,
							statusCode: res.statusCode
						});
						return;
					}

					const errorData = res.data as ApiError;
					resolve({
						success: false,
						error: {
							message: errorData?.message || `HTTP Error: ${res.statusCode}`,
							error: errorData?.error,
							statusCode: res.statusCode
						},
						statusCode: res.statusCode
					});
				},
				fail: (err: UniRequestFailResult) => {
					console.error("[API Proxy Error]", {
						errMsg: err.errMsg,
						errno: err.errno
					});

					resolve({
						success: false,
						error: {
							message: err.errMsg || "代理请求失败",
							statusCode: 0
						},
						statusCode: 0
					});
				}
			});
		});
	}

	/**
	 * 构建完整 URL（包含查询参数）
	 */
	private buildUrl(url: string, params?: Record<string, RequestParamValue>): string {
		let fullUrl = url.startsWith("http") ? url : `${this.config.baseUrl}${url}`;

		if (params) {
			const queryParts: string[] = [];
			for (const [key, value] of Object.entries(params)) {
				if (value !== null && value !== undefined) {
					queryParts.push(
						`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`
					);
				}
			}
			if (queryParts.length > 0) {
				fullUrl += (fullUrl.includes("?") ? "&" : "?") + queryParts.join("&");
			}
		}

		return fullUrl;
	}

	/**
	 * 发起请求
	 */
	request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>> {
		return new Promise((resolve) => {
			const fullUrl = this.buildUrl(config.url, config.params);

			const headers: Record<string, string> = {
				"Content-Type": "application/json",
				...config.header
			};

			// 添加 Authorization header
			if (this.config.accessToken) {
				headers["Authorization"] = `Bearer ${this.config.accessToken}`;
			}

			const requestMethod = config.method || "GET";

			// 处理请求数据
			// 对于 PATCH/PUT/POST 请求，如果 data 是对象，手动序列化为 JSON 字符串
			// 某些平台对复杂嵌套对象的自动序列化有问题
			let requestData: string | RequestData | undefined = config.data;
			if (
				config.data !== null &&
				config.data !== undefined &&
				["PATCH", "PUT", "POST"].includes(requestMethod)
			) {
				try {
					requestData = JSON.stringify(config.data);
					console.log("[API] Original data:", config.data);
					console.log("[API] Stringified data:", requestData);
					console.log("[API] Data type:", typeof requestData);
				} catch (e) {
					console.error("[API] Failed to stringify data:", e);
					requestData = config.data;
				}
			}

			console.log("[API Request]", {
				url: fullUrl,
				method: requestMethod,
				data: requestData,
				headers
			});

			uni.request({
				url: fullUrl,
				method: requestMethod,
				data: requestData,
				header: headers,
				timeout: config.timeout || 30000,
				success: (res: UniRequestSuccessResult) => {
					console.log("[API Response]", {
						statusCode: res.statusCode,
						data: res.data
					});

					// 2xx 状态码表示成功
					if (res.statusCode >= 200 && res.statusCode < 300) {
						resolve({
							success: true,
							data: res.data as T,
							statusCode: res.statusCode
						});
						return;
					}

					// 处理错误响应
					const errorData = res.data as ApiError;
					resolve({
						success: false,
						error: {
							message: errorData?.message || `HTTP Error: ${res.statusCode}`,
							error: errorData?.error,
							statusCode: res.statusCode
						},
						statusCode: res.statusCode
					});
				},
				fail: (err: UniRequestFailResult) => {
					console.error("[API Error]", {
						errMsg: err.errMsg,
						errno: err.errno,
						url: fullUrl
					});

					let errorMessage = "网络请求失败";
					if (err.errMsg) {
						if (err.errMsg.includes("timeout")) {
							errorMessage = "请求超时，请检查网络连接";
						} else if (err.errMsg.includes("fail")) {
							errorMessage = "连接失败，请检查网络";
						} else if (err.errMsg.includes("ssl")) {
							errorMessage = "SSL证书验证失败";
						} else {
							errorMessage = err.errMsg;
						}
					}

					resolve({
						success: false,
						error: {
							message: errorMessage,
							statusCode: 0
						},
						statusCode: 0
					});
				}
			});
		});
	}

	/**
	 * GET请求
	 */
	get<T = unknown>(
		url: string,
		params?: Record<string, RequestParamValue>,
		config?: Partial<RequestConfig>
	): Promise<ApiResponse<T>> {
		return this.request<T>({
			url,
			method: "GET",
			params,
			...config
		});
	}

	/**
	 * POST请求
	 */
	post<T = unknown>(
		url: string,
		data?: RequestData,
		config?: Partial<RequestConfig>
	): Promise<ApiResponse<T>> {
		return this.request<T>({
			url,
			method: "POST",
			data,
			...config
		});
	}

	/**
	 * PUT请求
	 */
	put<T = unknown>(
		url: string,
		data?: RequestData,
		config?: Partial<RequestConfig>
	): Promise<ApiResponse<T>> {
		return this.request<T>({
			url,
			method: "PUT",
			data,
			...config
		});
	}

	/**
	 * PATCH请求 - 通过代理服务器发送
	 */
	patch<T = unknown>(
		url: string,
		data?: RequestData,
		config?: Partial<RequestConfig>
	): Promise<ApiResponse<T>> {
		return this.requestViaProxy<T>({
			url,
			method: "PATCH",
			data,
			...config
		});
	}

	/**
	 * DELETE请求
	 */
	delete<T = unknown>(
		url: string,
		data?: RequestData,
		config?: Partial<RequestConfig>
	): Promise<ApiResponse<T>> {
		return this.request<T>({
			url,
			method: "DELETE",
			data,
			...config
		});
	}
}

// 导出请求实例
export const request = new Request();

// 默认导出
export default request;
